package com.fdb.efp.nls.service.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fdb.basic.framework.core.exception.BizException;
import com.fdb.basic.framework.core.util.DateTool;
import com.fdb.basic.framework.core.util.DateUtility;
import com.fdb.basic.framework.core.util.StringUtil;
import com.fdb.efp.nls.common.constant.BdLoanConstant;

/**
 * 
 * 获取同步文件数据
 * 
 * @author ludayong
 * @since 2019年5月16日 上午8:43:50
 * @version 1.0
 */
public class DueDataUtil {

	private static Logger logger = LoggerFactory.getLogger(DueDataUtil.class);

	/**
	 * 逗号转义符
	 */
	private static String QUOT_TRAN_SIGN = "<#>";

	/**
	 * 
	 * 获取同步文件数据 <br>
	 * 0.1:ludayong:2019年5月16日 上午9:06:55:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月16日 上午9:06:55
	 * @date 2019年5月16日 上午9:06:55
	 * @version 0.1
	 */
	public static String getFirstLineContext(String filePath) throws IOException, Exception {
		logger.info("**************************获取同步文件数据开始**************************");
		// 文件
		File file = null;
		// 文件流
		InputStreamReader reader = null;
		// 字符串
		BufferedReader br = null;
		// 文件读取内容
		String context = "";
		try {
			/************************** 1.获取文件 **************************/
			// 构建文件
			file = new File(filePath);
			// 解析文件
			if (file.isFile() && file.exists()) {
				// 构建文件流
				reader = new InputStreamReader(new FileInputStream(file), "utf-8");
				// 读取文件
				br = new BufferedReader(reader);
				if ((context = br.readLine()) != null) {
					// 获取信号文件记录数
					logger.info("获取同步文件数据为：" + context);
				} else {
					logger.error("同步文件数据首行为空！");
					throw new BizException("同步文件数据首行为空，请检查！");
				}
			} else {
				logger.error("同步文件不存在[" + filePath + "]，请检查！");
				throw new Exception("同步文件不存在[" + filePath + "]，请检查！");
			}
		} catch (BizException e) {
			logger.error("同步文件[" + filePath + "]，读取错误，异常信息：" + e.getMessage());
			e.printStackTrace();
			throw e;
		} catch (Exception e) {
			logger.error("同步文件[" + filePath + "]，读取错误，异常信息：" + e.getMessage());
			e.printStackTrace();
			throw e;
		} finally {
			if (reader != null) {
				reader.close();
			}
			if (br != null) {
				br.close();
			}
			logger.info("**************************获取同步文件数据结束**************************");
		}
		return context;
	}

	/**
	 * 
	 * 将百度并账文件标准化数据写入文件中 <br>
	 * 0.1:ludayong:2019年3月9日 上午10:43:27:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月9日 上午10:43:27
	 * @date 2019年3月9日 上午10:43:27
	 * @version 0.1
	 */
	public static <T> File writeOk(String filePath, String outputStr) throws Exception {
		OutputStreamWriter out = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			file = new File(filePath);
			if (file.exists()) {
				file.delete();
			}
			file.createNewFile();
			fos = new FileOutputStream(file);
			out = new OutputStreamWriter(fos, "UTF-8");
			out.write(outputStr);
			out.write("\r\n");
			logger.info("文件格式" + out.getEncoding());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e);
		} finally {
			if (out != null) {
				out.flush();
				out.close();
			}
			if (fos != null) {
				fos.flush();
				fos.close();
			}
		}
		return file;
	}

	/**
	 * 
	 * 获取对象的字段类型返回Map <br>
	 * 0.1:ludayong:2019年3月9日 上午10:43:27:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月9日 上午10:43:27
	 * @date 2019年3月9日 上午10:43:27
	 * @version 0.1
	 */
	public static Map<String, String> getObjectFieldType(Object object) throws Exception {
		// 实体类字段类型Map
		Map<String, String> fieldTypeMap = null;
		if (object != null) {
			// 实体类字段类型Map
			fieldTypeMap = new HashMap<String, String>();
			// 拿到该类
			Class<?> clz = object.getClass();
			// 获取实体类的所有属性，返回Field数组
			Field[] fields = clz.getDeclaredFields();
			for (Field field : fields) {
				// 字段类型
				String fieldType = field.getType().getName();
				// 字段名称
				String fieldName = field.getName();
				// 排除序列化信息
				if ("serialVersionUID".equals(fieldName)) {
					continue;
				}
				// 将字段信息放入实体类字段类型Map
				fieldTypeMap.put(getMethodName(fieldName), fieldType);
			}
		}
		return fieldTypeMap;
	}

	/**
	 * 
	 * 把一个字符串的第一个字母大写 <br>
	 * 0.1:ludayong:2019年3月9日 上午10:43:27:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年3月9日 上午10:43:27
	 * @date 2019年3月9日 上午10:43:27
	 * @version 0.1
	 */
	private static String getMethodName(String fildeName) throws Exception {
		byte[] items = fildeName.getBytes();
		items[0] = (byte) ((char) items[0] - 'a' + 'A');
		return new String(items);
	}

	/**
	 * 
	 * 校验数字是否为空，如需要进行单位转换，则转换返回<br>
	 * 0.1:weijj:2019年3月8日 下午5:01:37:新增 <br>
	 * 
	 * @author weijj
	 * @since 2019年3月8日 下午5:01:37
	 * @date 2019年3月8日 下午5:01:37
	 * @version 0.1
	 */
	public static BigDecimal checkDecimalInfo(BigDecimal dec, int unit) {
		BigDecimal newDec = dec == null ? BigDecimal.ZERO : dec;
		if (unit != 0) {
			newDec = newDec.divide(new BigDecimal(unit));
		}
		return newDec;
	}

	/**
	 * 
	 * 时间格式转换<br>
	 * 0.1:weijj:2019年3月20日 下午6:03:17:新增 <br>
	 * 
	 * @author weijj
	 * @since 2019年3月20日 下午6:03:17
	 * @date 2019年3月20日 下午6:03:17
	 * @version 0.1
	 */
	public static String formatDateTime10To19(String date) throws Exception {
		if (date == null || "".equals(date)) {
			return "";
		}
		if (date.length() != 10) {
			throw new Exception("时间：" + date + "格式不合规");
		}
		try {
			SimpleDateFormat sfl = new SimpleDateFormat(DateTool.PATTERN_DEFAULT);
			SimpleDateFormat sf2 = new SimpleDateFormat(DateTool.PATTERN_DATETIME);
			String dt = sf2.format(sfl.parse(date));
			return dt;
		} catch (Exception e) {
			throw new Exception("时间：" + date + "格式不合规");
		}
	}

	/**
	 * 
	 * 时间格式转换<br>
	 * 0.1:weijj:2019年3月20日 下午6:03:17:新增 <br>
	 * 
	 * @author weijj
	 * @since 2019年3月20日 下午6:03:17
	 * @date 2019年3月20日 下午6:03:17
	 * @version 0.1
	 */
	public static String formatTime6To8(String date) throws Exception {
		if (date == null || "".equals(date)) {
			return "";
		}
		if (date.length() != 6) {
			throw new Exception("时间：" + date + "格式不合规");
		}
		try {
			SimpleDateFormat sfl = new SimpleDateFormat(BdLoanConstant.PATTERN_TIME_DEFAULT);
			SimpleDateFormat sf2 = new SimpleDateFormat(BdLoanConstant.PATTERN_TIME_FORMAT);
			String dt = sf2.format(sfl.parse(date));
			return dt;
		} catch (Exception e) {
			throw new Exception("时间：" + date + "格式不合规");
		}
	}

	/**
	 * 
	 * 时间格式转换<br>
	 * 0.1:weijj:2019年3月20日 下午6:03:17:新增 <br>
	 * 
	 * @author weijj
	 * @since 2019年3月20日 下午6:03:17
	 * @date 2019年3月20日 下午6:03:17
	 * @version 0.1
	 */
	public static String dateInfoTrans(String date) {
		if (StringUtil.isNullorBank(date)) {// 时间为空时
			return "";
		} else {
			return DateUtility.format8To10(date);
		}
	}

	/**
	 * 
	 * 获取申请日的值 <br>
	 * 0.1:ludayong:2019年5月7日 下午2:29:10:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 下午2:29:10
	 * @date 2019年5月7日 下午2:29:10
	 * @version 0.1
	 */
	public static String getApplyDateValue(String trantime, String type) {
		// apply_date 申请日期 inputdate 录入日期
		String applyDate = "";
		if (!StringUtil.isNullorBank(trantime)) {
			long loanTranTime = (long) Double.parseDouble(trantime + "000");
			if (BdLoanConstant.YES_1.equals(type)) {
				applyDate = DateTool.formatDate(new Date(loanTranTime), DateTool.PATTERN_DATETIME);
			} else if (BdLoanConstant.NO_0.equals(type)) {
				applyDate = DateTool.formatDate(new Date(loanTranTime), DateTool.PATTERN_DEFAULT);
			} else {
				applyDate = DateTool.formatDate(new Date(loanTranTime), BdLoanConstant.PATTERN_TIME_FORMAT);
			}
		}
		return applyDate;
	}

	/**
	 * 
	 * 获取创建时间的值 <br>
	 * 0.1:ludayong:2019年5月7日 下午2:29:10:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月7日 下午2:29:10
	 * @date 2019年5月7日 下午2:29:10
	 * @version 0.1
	 */
	public static String getCreateTimeValue(String etlDate) {
		// create_time 申请日期 etl_date 数据采集日期
		String createTime = "";
		if (!StringUtil.isNullorBank(etlDate)) {
			createTime = etlDate + " 00:00:00";
		}
		return createTime;
	}

	/**
	 * 
	 * 获取同步文件数据 <br>
	 * 0.1:ludayong:2019年5月16日 上午9:06:55:新增 <br>
	 * 
	 * @author ludayong
	 * @since 2019年5月16日 上午9:06:55
	 * @date 2019年5月16日 上午9:06:55
	 * @version 0.1
	 */
	public static String getLineContext(String filePath, int start) throws IOException, Exception {
		logger.info("**************************获取同步文件数据开始**************************");
		// 文件
		File file = null;
		// 文件流
		InputStreamReader reader = null;
		// 字符串
		BufferedReader br = null;
		// 文件读取内容
		String context = "";
		try {
			/************************** 1.获取文件 **************************/
			// 构建文件
			file = new File(filePath);
			// 解析文件
			if (file.isFile() && file.exists()) {
				// 构建文件流
				reader = new InputStreamReader(new FileInputStream(file), "utf-8");
				// 读取文件
				br = new BufferedReader(reader);
				// 判断是否需要去除首行
				if (start != 0) {
					// 去除首行
					for (int i = 0; i < start; i++) {
						br.readLine();
					}
				}
				if ((context = br.readLine()) != null) {
					// 获取信号文件记录数
					logger.info("获取同步文件数据为：" + context);
				} else {
					logger.error("读取同步文件数据首行为空！");
					throw new BizException("读取同步文件数据为空，请检查！");
				}
			} else {
				logger.error("同步文件不存在[" + filePath + "]，请检查！");
				throw new Exception("同步文件不存在[" + filePath + "]，请检查！");
			}
		} catch (BizException e) {
			logger.error("同步文件[" + filePath + "]，读取错误，异常信息：" + e.getMessage());
			e.printStackTrace();
			throw e;
		} catch (Exception e) {
			logger.error("同步文件[" + filePath + "]，读取错误，异常信息：" + e.getMessage());
			e.printStackTrace();
			throw e;
		} finally {
			if (reader != null) {
				reader.close();
			}
			if (br != null) {
				br.close();
			}
			logger.info("**************************获取同步文件数据结束**************************");
		}
		return context;
	}

	/**
	 *
	 * 将数据追加写入文件中 <br>
	 * 0.1:ludayong:2019年11月21日 下午11:30:13:新增 <br>
	 *
	 * @author ludayong
	 * @since 2019年11月21日 下午11:30:13
	 * @date 2019年11月21日 下午11:30:13
	 * @version 0.1
	 */
	public static <T> File writeOkAppend(String filePath, String outputStr) throws Exception {
		OutputStreamWriter out = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			file = new File(filePath);
			if (!file.exists()) {
				file.createNewFile();
			}
			fos = new FileOutputStream(file,true);
			out = new OutputStreamWriter(fos, "UTF-8");
			out.write(outputStr);
			out.write("\r\n");
			logger.info("文件格式" + out.getEncoding());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e);
		} finally {
			if (out != null) {
				out.flush();
				out.close();
			}
			if (fos != null) {
				fos.flush();
				fos.close();
			}
		}
		return file;
	}


	/**
	 *
	 * @Description 将数据写入传入的file中
	 * @param file
	 * @param lists
	 * @return
	 * @throws Exception
	 */
	public static <T> File writeTxt(String filePath, List<T> lists, String operation) throws Exception {
		OutputStreamWriter out = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			file = new File(filePath);
			if (!file.exists()) {
				file.createNewFile();
			}
			fos = new FileOutputStream(file,true);
			// out = new OutputStreamWriter(fos,"GBK");
			out = new OutputStreamWriter(fos, "UTF-8");
			for (T t : lists) {
				// String outputStr = ReflectionToStringBuilder.reflectionToString(t,
				// ToStringStyle.SHORT_PREFIX_STYLE);B
				String outputStr = (new ReflectionToStringBuilder(t, ToStringStyle.NO_FIELD_NAMES_STYLE) {

					@Override
					protected Object getValue(Field field) throws IllegalArgumentException, IllegalAccessException {
						if (field.getType().isAssignableFrom(BigDecimal.class)) {
							Object value = super.getValue(field);
							if (value != null) {
								return ((BigDecimal) super.getValue(field)).toPlainString();
							} else {
								return value;
							}
						} else if (field.getType().isAssignableFrom(String.class)) {
							Object value = super.getValue(field);
							if (value != null) {
								String val = (String) value;
								// 判断字符字符中是否含有逗号，有则先转义
								if (val.contains(",")) {
									val = val.replace(",", QUOT_TRAN_SIGN);
								}
								return val;
							} else {
								return value;
							}

						} else {
							return super.getValue(field);
						}
					}

				}).toString();
				outputStr = outputStr.substring(outputStr.indexOf("[") + 1, outputStr.lastIndexOf("]")).replace(",", operation)
						.replace("<null>", "");
				// 逗号转义
				outputStr = outputStr.replace(QUOT_TRAN_SIGN, ",");
				out.write(outputStr);
				out.write("\r\n");
			}
			logger.info("文件格式" + out.getEncoding());
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new RuntimeException(e);
		} finally {
			if (out != null) {
				out.flush();
				out.close();
			}
			if (fos != null) {
				fos.flush();
				fos.close();
			}
		}
		return file;
	}
}
